#include "ImaDbInterface.h"
#include "ImaGlobals.h"
#include "ImaConstants.h"
#include "string.h"

ImaDbInterface* ImaDbInterface::mpDbInterface = NULL;

ImaDbInterface* ImaDbInterface::getInstance(ImaConf& conf) {
	if(mpDbInterface == NULL) {
		LOG(debug, __FILE__, __LINE__, "creating DB interface object");
		mpDbInterface = new ImaDbInterface(conf);
		if( 0 != mpDbInterface->connectToDb()) {
			delete mpDbInterface;
			mpDbInterface = NULL;
		}
	}
	return mpDbInterface;
}

ImaDbInterface::ImaDbInterface(ImaConf& conf): mpConn(NULL) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::ImaDbInterface() called");

	strcpy(mDbHostname, conf.mDbHostname);
	mDbPort = conf.mDbPort;
	strcpy(mDbName, conf.mDbName);
	strcpy(mDbUsername, conf.mDbUsername);
	strcpy(mDbPassword, conf.mDbPassword);
}

ImaDbInterface::~ImaDbInterface() {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::~ImaDbInterface() called");

	if(mpConn != NULL) {
		PQfinish(mpConn);
		mpConn = NULL;
	}
}

int ImaDbInterface::connectToDb() {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::connectToDb() called");

	char dbConnString[1024];
	sprintf(dbConnString, "hostaddr = '%s' port = '%d' dbname = '%s' \
				user = '%s' password = '%s' connect_timeout = '%d'",
				mDbHostname, mDbPort, mDbName, mDbUsername, mDbPassword, IMA_DB_CONN_TIMEOUT);
	int retVal = -1;

	for(int i = 0; i < IMA_NUM_DB_CONN_RETRIES; i++) {
		mpConn = PQconnectdb(dbConnString);
		if(PQstatus(mpConn) != CONNECTION_OK) {
			char log_msg[1024];
			sprintf(log_msg, "Failed to connect to DB in %d attempt(s); DB conn string: %s ; Error message: %s", i, dbConnString, PQerrorMessage(mpConn));
			LOG(error, __FILE__, __LINE__, log_msg);
		} else {
			char log_msg[1024];
			sprintf(log_msg, "Connection to DB successful in %d attempt(s); DB conn string: %s", i, dbConnString);
			LOG(info, __FILE__, __LINE__, log_msg);
			retVal = 0;
			break;
		}
	}

	return retVal;
}


//int ImaDbInterface::fetchUserId(const char* pEmailId, string& userId) {
//	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::fetchUserId called");
//
//	char query_string[256];
//	int retVal = 1;
//	sprintf(query_string, "select user_id \
//		from tbl_user where email_id = '%s'", pEmailId);
//
//	PGresult* pRes = NULL;
//	pRes = PQexec(mpConn, query_string);
//	
//	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
//		userId = string(PQgetvalue(pRes, 0, 0));
//		char log_msg[1024];
//		sprintf(log_msg, "The user id for email id %s is %s", pEmailId, userId.c_str());
//		retVal = 1;
//	} else {
//		char log_msg[512];
//		sprintf(log_msg, "Failed to fetch the user id for email id %s", pEmailId);
//		LOG(info, __FILE__, __LINE__, log_msg);
//		retVal = 0;
//	}
//	//TODO: also handle database error
//	PQclear(pRes);
//
//	return retVal;;
//}

int ImaDbInterface::isRegisteredUser(const char* pEmailId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::isRegisteredUser called");

	char query_string[256];
	int retVal = 1;
	sprintf(query_string, "select email_id \
		from tbl_user where email_id = '%s'", pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		char log_msg[512];
		sprintf(log_msg, "The user %s is already registered", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "The user %s is not registered", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;;
}

//int ImaDbInterface::isRegisteredUser(const unsigned long& userId) {
//	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::isRegisteredUser called");
//
//	char query_string[256];
//	int retVal = 1;
//	sprintf(query_string, "select user_id \
//		from tbl_user where user_id = '%lu'", userId);
//
//	PGresult* pRes = NULL;
//	pRes = PQexec(mpConn, query_string);
//	
//	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
//		char log_msg[512];
//		sprintf(log_msg, "The user %lu is already registered", userId);
//		LOG(info, __FILE__, __LINE__, log_msg);
//		retVal = 1;
//	} else {
//		char log_msg[512];
//		sprintf(log_msg, "The user %lu is not registered", userId);
//		LOG(info, __FILE__, __LINE__, log_msg);
//		retVal = 0;
//	}
//	//TODO: also handle database error
//	PQclear(pRes);
//
//	return retVal;;
//}


char ImaDbInterface::getUserRegistrationStatus(const char* pEmailId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::getUserRegistrationStatus called");

	char query_string[256];
	sprintf(query_string, "select registration_status \
		from tbl_user where email_id = '%s'", pEmailId);

	char regnStatus = IMA_REGN_NOT_REGISTERED;
	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);

	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		//TODO: extract the registration status
		regnStatus = *(PQgetvalue(pRes, 0, 0));	
		char log_msg[512];
		sprintf(log_msg, "The registration status of %s is %c", pEmailId, regnStatus);
		LOG(info, __FILE__, __LINE__, log_msg);
		PQclear(pRes);
		return regnStatus;
	} else {
		char log_msg[512];
		sprintf(log_msg, "The user %s is not registered", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
	}
	PQclear(pRes);

	return regnStatus;
}

int ImaDbInterface::areUserCredentialsCorrect(const char* pEmailId, const char* pPassword) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::areUserCredentialsCorrect called ");

	char query_string[256];
	sprintf(query_string, "select registration_status \
		from tbl_user where email_id = '%s' and password = '%s'", 
		pEmailId, pPassword);

	int retVal = 1;
	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		char log_msg[512];
		sprintf(log_msg, "The user  credentials of %s is are correct", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "The user credentials of %s is incorrect", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::isUserRegnConfCodeCorrect(const char* pEmailId, const char* pConfCode) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::isUserRegnConfCodeCorrect called ");

	char query_string[256];
	sprintf(query_string, "select * \
		from tbl_user where email_id = '%s' and confirmation_code = '%s'", 
		pEmailId, pConfCode);

	int retVal = 1;
	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		char log_msg[512];
		sprintf(log_msg, "The confirmation code of %s is correct", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "The confirmation code of %s is incorrect", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::changePassword(const char* pEmailId, const char* pCurrPassword, const char* pNewPassword) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::changePassword called with emailid : %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	int retVal = 1;
	
	char query_string[2048];
	sprintf(query_string, "update tbl_user SET password='%s' \
			where email_id='%s' and password='%s'", pNewPassword, pEmailId, pCurrPassword);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		retVal = 1;
		sprintf(log_msg, "password of user %s updated", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
	} else {
		retVal = -1;
		sprintf(log_msg, "Failed to update password of %s. Reason: %s ", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::resetPassword(const char* pEmailId, const char* pNewPassword) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::resetPassword called with emailid : %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	int retVal = 1;
	
	char query_string[2048];
	sprintf(query_string, "update tbl_user SET password='%s' \
			where email_id='%s'", pNewPassword, pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		retVal = 1;
		sprintf(log_msg, "password of user %s has been reset", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
	} else {
		retVal = -1;
		sprintf(log_msg, "Failed to reset password of %s. Reason: %s ", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
	}

	PQclear(pRes);

	return retVal;

}

int ImaDbInterface::fetchPassword(const char* pEmailId, std::string& strPassword) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::fetchPassword called");

	unsigned long retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select password from tbl_user where email_id='%s'", pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		strPassword = std::string(PQgetvalue(pRes, 0, 0));
		char log_msg[1024];
		sprintf(log_msg, "The password of user %s fetched from DB", pEmailId);
		LOG(debug, __FILE__, __LINE__, log_msg);		
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the password for user id %s", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::fetchImId(const char* pEmailId, std::string& strImId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::fetchImId called");

	unsigned long retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select im_id from tbl_user where email_id='%s'", pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		strImId = std::string(PQgetvalue(pRes, 0, 0));
		char log_msg[1024];
		sprintf(log_msg, "The IM ID of user %s fetched from DB is %s", pEmailId, strImId.c_str());
		LOG(debug, __FILE__, __LINE__, log_msg);		
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the IM ID for user id %s", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::setBuddyAddedStatus(const char* pEmailId, const char* pStatus) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::setBuddyAddedStatus called");

	unsigned long retVal = 0;
	char query_string[1024];
	sprintf(query_string, "update tbl_user SET buddy_added_status='%s' where email_id='%s'", pStatus, pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_TUPLES_OK){
		char log_msg[1024];
		sprintf(log_msg, "Updated the buddy_added_status of the user %s to %s", pEmailId, pStatus);
		LOG(debug, __FILE__, __LINE__, log_msg);		
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to update the buddy_added_status of the user id %s to %s", pEmailId, pStatus);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

//int ImaDbInterface::fetchInfoId(const unsigned long& userId, const char* pInfo, const int& media, const char* pExpiryData, const unsigned long& ttl, unsigned long& infoId) {
//	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::fetchInfoId called");
//
//	unsigned long retVal = 0;
//	char query_string[1024];
//	sprintf(query_string, "select info_id from tbl_info where owner_id='%lu' and info='%s' and media='%d' and doe='%s' and ttl='%lu'", userId, pInfo, media, pExpiryData, ttl);
//
//	PGresult* pRes = NULL;
//	pRes = PQexec(mpConn, query_string);
//	
//	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
//		infoId = atol(PQgetvalue(pRes, 0, 0));
//		char log_msg[1024];
//		sprintf(log_msg, "The info id for user id %lu and info %s  is %lu", userId, pInfo, infoId);
//		LOG(debug, __FILE__, __LINE__, log_msg);		
//		retVal = 1;
//	} else {
//		char log_msg[512];
//		sprintf(log_msg, "Failed to fetch the infoid for user id %lu and info %s", userId, pInfo);
//		LOG(info, __FILE__, __LINE__, log_msg);
//		retVal = 0;
//	}
//	//TODO: also handle database error
//	PQclear(pRes);
//
//	return retVal;
//}

//int ImaDbInterface::addInfo(const unsigned long& userId, const char* pInfo, const int& media, const char* pExpiryDate, unsigned long& ttl) {
//	char log_msg[512];
//	sprintf(log_msg, "ImaDbInterface::addInfo called with userid: %lu", userId);
//	LOG(debug, __FILE__, __LINE__, log_msg);
//	int retVal = -1;
//	
//	char query_string[2048];
//	sprintf(query_string, "insert into tbl_info \
//			(owner_id, info, media, doc, doe, ttl) \
//			values ('%lu', '%s', '%d', CURRENT_DATE, '%s', '%lu')", 
//			userId, pInfo, media, pExpiryDate, ttl);
//
//	PGresult* pRes = NULL;
//	pRes = PQexec(mpConn, query_string);
//	
//	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
//		sprintf(log_msg, "Added new info from %lu with info = %s", userId, pInfo);
//		LOG(info, __FILE__, __LINE__, log_msg);
//		retVal = 1;
//	} else {
//		sprintf(log_msg, "Failed to add new info from %lu, Error: %s", userId, PQresultErrorMessage(pRes));
//		LOG(error, __FILE__, __LINE__, log_msg);
//		sprintf(log_msg, "SQL string is %s", query_string);
//		LOG(error, __FILE__, __LINE__, log_msg);
//		retVal = -1;
//	}
//
//	PQclear(pRes);
//
//	return retVal;
//}

int ImaDbInterface::fetchInfoId(const char* pEmailId, const char* pInfo, const int& media, const char* pExpiryData, const unsigned long& ttl, std::string& strInfoId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::fetchInfoId called");

	unsigned long retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select info_id from tbl_info where owner_email_id='%s' and info='%s' and media='%d' and ttl='%lu'", pEmailId, pInfo, media, ttl);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		strInfoId = std::string(PQgetvalue(pRes, 0, 0));
		char log_msg[1024];
		sprintf(log_msg, "The info id for user id %s and info %s  is %s", pEmailId, pInfo, strInfoId.c_str());
		LOG(debug, __FILE__, __LINE__, log_msg);		
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the infoid for user id %s and info %s", pEmailId, pInfo);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::addInfo(const char* pEmailId, const char* pInfo, int media, const char* pExpiryDate, unsigned long ttl) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::addInfo called with email id: %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	long retVal = -1;
	
	char query_string[2048];
	sprintf(query_string, "insert into tbl_info \
			(owner_email_id, info, media, doc, ttl) \
			values ('%s', '%s', '%d', CURRENT_DATE, '%lu')", 
			pEmailId, pInfo, media, ttl);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		sprintf(log_msg, "Added new info from %s with info = %s", pEmailId, pInfo);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		sprintf(log_msg, "Failed to add new info from %s, Error: %s", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::updateInfo(const unsigned long& infoId, const char* pInfo, const char* pDateOfExpiry, unsigned long& ttl) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::updateInfo called with infoId: %ld and info: %s", infoId, pInfo);
	LOG(debug, __FILE__, __LINE__, log_msg);
	int retVal = 1;
	
	char query_string[2048];
	sprintf(query_string, "update tbl_info SET info='%s' \
			where info_id = '%ld'",	pInfo, infoId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		retVal = 1;
		sprintf(log_msg, "Info with Id %ld updated", infoId);
		LOG(info, __FILE__, __LINE__, log_msg);
	} else {
		retVal = -1;
		sprintf(log_msg, "Info with Id %ld failed to be updated. Reason: %s ", infoId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::deleteInfo(const unsigned long& infoId, const char* pEmailId) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::deleteInfo called with info id: %ld", infoId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	short retVal = 0;

	if(1 != deleteInfoIdReferences(infoId)) {
		LOG(error, __FILE__, __LINE__, "Failed to delete info id references from tbl_info_recipient");
		return -1;
	}
	
	char query_string[1024];
	sprintf(query_string, "delete from tbl_info \
			where info_id = '%ld' and owner_email_id='%s'", infoId, pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) != PGRES_COMMAND_OK) {
		retVal = -1;
		sprintf(log_msg, "Failed to delete info with id: %ld, Reason %s", infoId, PQresultErrorMessage(pRes) );
		LOG(error, __FILE__, __LINE__, log_msg);
	} else {
		retVal = 1;
		sprintf(log_msg, "deleted info with id: %ld", infoId);
		LOG(info, __FILE__, __LINE__, log_msg);
	}

	LOG(info, __FILE__, __LINE__, log_msg);
	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::deleteInfoIdReferences(const unsigned long& infoId) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::deleteInfoIdReferences called with info id: %ld", infoId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	short retVal = 0;
	
	char query_string[1024];
	sprintf(query_string, "delete from tbl_info_recipient \
			where info_id = '%ld'", infoId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) != PGRES_COMMAND_OK) {
		retVal = -1;
		sprintf(log_msg, "Failed to delete info id (%ld) references from tbl_info_recipient;  Reason %s", infoId, PQresultErrorMessage(pRes) );
		LOG(error, __FILE__, __LINE__, log_msg);
	} else {
		retVal = 1;
		sprintf(log_msg, "deleted all references of info id: %ld", infoId);
		LOG(info, __FILE__, __LINE__, log_msg);
	}

	LOG(info, __FILE__, __LINE__, log_msg);
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::isRegisteredInfo(const unsigned long& infoId, const char* pEmailId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::isRegisteredInfo called");

	char query_string[256];
	int retVal = 1;
	sprintf(query_string, "select owner_email_id \
		from tbl_info where info_id = %lu and owner_email_id = '%s'", 
		infoId, pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		char log_msg[512];
		sprintf(log_msg, "The info %lu is registered", infoId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "The info id %lu is not registered. Reason: %s", infoId, PQresultErrorMessage(pRes));
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::isRegisteredRecipient(const unsigned long& recipientId, const char* pEmailId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::isRegisteredRecipient called");
	if(recipientId < 1) {
		return 0;
	}

	char query_string[256];
	int retVal = 1;
	sprintf(query_string, "select owner_email_id \
		from tbl_recipient where recipient_id = %lu and owner_email_id = '%s'", 
		recipientId, pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		char log_msg[512];
		sprintf(log_msg, "The recipient %lu is registered", recipientId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "The recipient id %lu is not registered. Reason: %s", recipientId, PQresultErrorMessage(pRes));
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::registerRecipient(const char* pRecipientName, const char* pRecipientEmailId, const char* pRecipientPhone, const char* pRecipientAddress, const char* pRelationWithOwner, const char* pOwnerEmailId) {
	char log_msg[1024];
	sprintf(log_msg, "ImaDbInterface::registerRecipient called with name: %s, emailid: %s, phone: %s, address: %s relationship: %s", pRecipientName, pRecipientEmailId, pRecipientPhone, pRecipientAddress, pRelationWithOwner);
	LOG(debug, __FILE__, __LINE__, log_msg);

	long retVal = -1;
	
	char query_string[2048];
	sprintf(query_string, "insert into tbl_recipient \
			(recipient_name, recipient_address, recipient_email_id, recipient_phone_num, relation_with_owner, owner_email_id, doc) \
			values ('%s', '%s', '%s', '%s', '%s', '%s', CURRENT_TIMESTAMP)",
			pRecipientName, pRecipientAddress, pRecipientEmailId, pRecipientPhone, pRelationWithOwner, pOwnerEmailId); 

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		sprintf(log_msg, "Registered new recipient from %s with recipient email %s", pOwnerEmailId, pRecipientEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		sprintf(log_msg, "Failed to add new recipient with email %s from %s, Error: %s", pRecipientEmailId, pOwnerEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::fetchRecipientId(const char* pRecipientName, const char* pRecipientAddress, const char* pRecipientEmailId, const char* pRecipientPhone, const char* pRelationWithOwner, const char* pOwnerEmailId, std::string& strRecipientId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::fetchRecipientId called");

	int retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select recipient_id from tbl_recipient where recipient_name='%s' and recipient_address='%s' and recipient_email_id='%s' and recipient_phone_num='%s' and relation_with_owner='%s' and owner_email_id='%s'", pRecipientName, pRecipientAddress, pRecipientEmailId, pRecipientPhone, pRelationWithOwner, pOwnerEmailId); 

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		strRecipientId = std::string(PQgetvalue(pRes, 0, 0));
		char log_msg[1024];
		sprintf(log_msg, "The recipeint ID id for owner email id %s is %s", pOwnerEmailId, strRecipientId.c_str());
		LOG(debug, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the recipient ID for user id %s, Error: %s", pOwnerEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::addInfoRecipient(const unsigned long& infoId, const unsigned long& recipientId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::addInfoRecipient called");

	long retVal = -1;
	char log_msg[1024];
	
	char query_string[2048];
	sprintf(query_string, "insert into tbl_info_recipient \
			(info_id, recipient_id) \
			values('%lu', '%lu')", infoId, recipientId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		sprintf(log_msg, "Added new info reciepient %lu for info id %lu", recipientId, infoId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		sprintf(log_msg, "Failed to add new recipient %lu for info id %lu, Reason: %s", recipientId, infoId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::updateRecipient(const unsigned long& recipientId, const char* pRecipientName, const char* pRecipientEmailId, const char* pRecipientPhone, const char* pRecipientAddress, const char* pRecipientRelationship) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::updateRecipient called");

	long retVal = -1;
	char log_msg[1024];
	
	char query_string[2048];
	sprintf(query_string, "update tbl_recipient SET recipient_address='%s', recipient_email_id='%s', recipient_phone_num='%s', relation_with_owner='%s' where recipient_id='%lu'", pRecipientAddress, pRecipientEmailId, pRecipientPhone, pRecipientRelationship, recipientId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		sprintf(log_msg, "Updated reciepient %lu", recipientId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		sprintf(log_msg, "Failed to update recipient %lu, Reason: %s", recipientId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::deleteRecipient(const unsigned long& recipientId, const char* pOwnerEmailId) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::deleteRecipient called");

	long retVal = -1;
	char log_msg[1024];
	
	char query_string[2048];
	sprintf(query_string, "delete from tbl_info_recipient \
			where recipient_id = '%lu'", recipientId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		sprintf(log_msg, "Deleted all refernces related to recipient %lu from tbl_info_recipient", recipientId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
		sprintf(query_string, "delete from tbl_recipient \
			where recipient_id = '%lu'", recipientId);
		PGresult* pRes1 = NULL;
		pRes1 = PQexec(mpConn, query_string);
		if(PQresultStatus(pRes1) == PGRES_COMMAND_OK) {
			sprintf(log_msg, "Deleted  recipient %lu from tbl_recipient", recipientId);
			LOG(info, __FILE__, __LINE__, log_msg);
			retVal = 1;
		} else {
			sprintf(log_msg, "Failed to delete recipient %lu from tbl_recipient", recipientId);
			LOG(info, __FILE__, __LINE__, log_msg);
			retVal = -1;
		}
		PQclear(pRes1);
	} else {
		sprintf(log_msg, "Failed to delete rows corresponding to recipient %lu from tbl_info_recipient, Reason: %s", recipientId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::deleteRecipientIdReferences(const unsigned long& recipientId) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::deleteRecipientIdReferences called with recipient id: %ld", recipientId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	short retVal = 0;
	
	char query_string[1024];
	sprintf(query_string, "delete from tbl_info_recipient \
			where recipient_id = '%ld'", recipientId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) != PGRES_COMMAND_OK) {
		retVal = -1;
		sprintf(log_msg, "Failed to delete recipient id (%ld) references from tbl_info_recipient;  Reason %s", recipientId, PQresultErrorMessage(pRes) );
		LOG(error, __FILE__, __LINE__, log_msg);
	} else {
		retVal = 1;
		sprintf(log_msg, "deleted all references of recipient id: %ld from tbl_info_recipient", recipientId);
		LOG(info, __FILE__, __LINE__, log_msg);
	}

	LOG(info, __FILE__, __LINE__, log_msg);
	PQclear(pRes);

	return retVal;
}


//int ImaDbInterface::addInfoRecipient(const char* pRecipientName, const char* pRecipientAddress, const char* pRecipientEmailId, const char* pRecipientPhone, const char* pRelationWithOwner, const unsigned long& infoId, const char* pOwnerEmailId) {
//	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::addInfoRecipient called");
//
//	long retVal = -1;
//	char log_msg[1024];
//	
//	char query_string[2048];
//	sprintf(query_string, "insert into tbl_info_recipient \
//			(recipient_name, recipient_address, recipient_email_id, \
//			recipient_phone_num, relation_with_info_owner, info_id) \
//			values('%s', '%s', '%s', '%s', '%s', '%lu')", pRecipientName,
//			pRecipientAddress, pRecipientEmailId, pRecipientPhone, 
//			pRelationWithOwner, infoId); 
//
//	PGresult* pRes = NULL;
//	pRes = PQexec(mpConn, query_string);
//	
//	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
//		sprintf(log_msg, "Added new info reciiepient for info id %lu", infoId);
//		LOG(info, __FILE__, __LINE__, log_msg);
//		retVal = 1;
//	} else {
//		sprintf(log_msg, "Failed to add new info info recipient for info id %lu, Reason: %s", infoId, PQresultErrorMessage(pRes));
//		LOG(error, __FILE__, __LINE__, log_msg);
//		sprintf(log_msg, "SQL string is %s", query_string);
//		LOG(error, __FILE__, __LINE__, log_msg);
//		retVal = -1;
//	}
//
//	PQclear(pRes);
//
//	return retVal;
//}

int ImaDbInterface::deleteInfoRecipient(const unsigned long& recipientId, const unsigned long& infoId) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::deleteInfoRecipient called with recipient id: %lu and info id %lu", recipientId, infoId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	int retVal = 0;
	
	char query_string[1024];
	sprintf(query_string, "delete from tbl_info_recipient \
			where recipient_id = '%lu' and info_id = '%lu'", recipientId, infoId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) != PGRES_COMMAND_OK) {
		retVal = -1;
		sprintf(log_msg, "Failed to delete recipient with id: %lu and info id: %lu, Reason %s", recipientId, infoId, PQresultErrorMessage(pRes) );
		LOG(error, __FILE__, __LINE__, log_msg);
	} else {
		retVal = 1;
		sprintf(log_msg, "deleted info id %lu with recipient id: %lu", infoId, recipientId);
		LOG(info, __FILE__, __LINE__, log_msg);
	}

	LOG(info, __FILE__, __LINE__, log_msg);
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::registerNewUser(const char* pEmailId, 
				const char* pPassword, const char* pName, char gender, 
				const char*pAddress, const char* pCity, const char* pState, 
				const char* pCountry, const char* pZip,
				const char* pPhone, const char* pDob, 
				const char* pImId, const char* pImService, const char* pRegConfCode) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::registerNewUser called with email id: %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	
	char query_string[2048];
	if(strlen(pDob) > 0) {
		sprintf(query_string, "insert into tbl_user (email_id, password, name, gender, address, city, state, country, zip_code, phone, dob, doj, dola, registration_status, im_id, im_service, confirmation_code) values ('%s', '%s', '%s', '%c', '%s', '%s', '%s', '%s', '%s', '%s', date '%s', CURRENT_DATE, CURRENT_TIMESTAMP, '%c', '%s', '%s', '%s')", pEmailId, pPassword, pName, gender, pAddress, pCity, pState, pCountry, pZip, pPhone, pDob, IMA_REGN_CONF_PENDING, pImId, pImService, pRegConfCode);
	} else {
		sprintf(query_string, "insert into tbl_user (email_id, password, name, gender, address, city, state, country, zip_code, phone, doj, dola, registration_status, im_id, im_service, confirmation_code) values ('%s', '%s', '%s', '%c', '%s', '%s', '%s', '%s', '%s', '%s', CURRENT_DATE, CURRENT_TIMESTAMP, '%c', '%s', '%s', '%s')", pEmailId, pPassword, pName, gender, pAddress, pCity, pState, pCountry, pZip, pPhone, IMA_REGN_CONF_PENDING, pImId, pImService, pRegConfCode);
	}

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);

	int retVal = 1;
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		char log_msg[512];
		sprintf(log_msg, "The user %s has been registered", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "User registration of %s failled. Reason: %s ", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	sprintf(log_msg, "SQL string is %s", query_string);
	LOG(error, __FILE__, __LINE__, log_msg);

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::updateUserDetails(const char* pEmailId, const char* pImId, const char* pName,
		const char*pAddress, const char* pCity, const char* pState,
		const char* pCountry, const char* pZip, const char* pPhone,
		const char* pGender, const char* pDob) {
	LOG(debug, __FILE__, __LINE__, "ImaDbInterface::updateUserDetails called");

	long retVal = -1;
	char log_msg[1024];
	
	char query_string[2048];
	sprintf(query_string, "update tbl_user SET im_id='%s', name='%s', address='%s', city='%s', state='%s', country='%s', zip_code='%s', phone='%s', gender='%s' where email_id='%s'", pImId, pName, pAddress, pCity, pState, pCountry, pZip, pPhone, pGender, pEmailId);
		
	sprintf(log_msg, "SQL string is %s", query_string);
	LOG(debug, __FILE__, __LINE__, log_msg);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		sprintf(log_msg, "Updated user details of user %s", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		sprintf(log_msg, "Failed to update details of user %s, Reason: %s", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::confirmUserRegistration(const char* pEmailId) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::confirmRegistrationStatus called with email ID: %s", pEmailId); 
	LOG(debug, __FILE__, __LINE__, log_msg);
	int retVal = 1;
	
	char query_string[2048];
	sprintf(query_string, "update tbl_user SET registration_status='%c', dola=CURRENT_TIMESTAMP where email_id='%s'", IMA_REGN_CONFIRMED, pEmailId);

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		retVal = 1;
		sprintf(log_msg, "Updated the status of user %s to %c", pEmailId, IMA_REGN_CONFIRMED); 
		LOG(info, __FILE__, __LINE__, log_msg);
	} else {
		retVal = -1;
		sprintf(log_msg, "Failed to update the status of user %s to confirmed; Error: %s", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::updateLastAccessTime(const char* pEmailId) {
	char log_msg[512];
	sprintf(log_msg, "ImaDbInterface::updateLastAccessTime called with email id: %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);
	
	char query_string[2048];

	sprintf(query_string, "update tbl_user SET dola=CURRENT_TIMESTAMP \
			where email_id='%s'", pEmailId);
	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);

	int retVal = 1;
	
	if(PQresultStatus(pRes) == PGRES_COMMAND_OK) {
		char log_msg[512];
		sprintf(log_msg, "The last access time of the user %s has been updated", pEmailId);
		LOG(info, __FILE__, __LINE__, log_msg);
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to update the last access time of the user %s. Reason: %s ", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		sprintf(log_msg, "SQL string is %s", query_string);
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = -1;
	}

	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::fetchUserDetails(const char* pEmailId, std::string& strName, std::string& strAddress, std::string& strCity, std::string& strState, std::string& strCountry, std::string& strZip, std::string& strPhone, std::string& strDob, std::string& strGender, std::string& strImId, std::string& strImService) {
	char log_msg[1024];
	sprintf(log_msg, "ImaDbInterface::fetchUserDetails called with emailid: %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);

	int retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select name, address, city, state, country, zip_code, phone, dob, gender, im_id, im_service from tbl_user where email_id='%s'", pEmailId); 

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if((PQresultStatus(pRes) == PGRES_TUPLES_OK) && PQntuples(pRes)){
		strName = std::string(PQgetvalue(pRes, 0, 0));
		strAddress = std::string(PQgetvalue(pRes, 0, 1));
		strCity = std::string(PQgetvalue(pRes, 0, 2));
		strState = std::string(PQgetvalue(pRes, 0, 3));
		strCountry = std::string(PQgetvalue(pRes, 0, 4));
		strZip = std::string(PQgetvalue(pRes, 0, 5));
		strPhone = std::string(PQgetvalue(pRes, 0, 6));
		strDob = std::string(PQgetvalue(pRes, 0, 7));
		strGender = std::string(PQgetvalue(pRes, 0, 8));
		strImId = std::string(PQgetvalue(pRes, 0, 9));
		strImService = std::string(PQgetvalue(pRes, 0, 10));
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the user detils for email id %s, Error: %s", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::fetchRecipientList(const char* pEmailId, std::vector<RECIPIENT_DETAILS*>& recipientList) {
	char log_msg[1024];
	sprintf(log_msg, "ImaDbInterface::fetchRecipientsList called with emailid: %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);

	int retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select recipient_id, recipient_name, recipient_email_id, recipient_phone_num, recipient_address, relation_with_owner from tbl_recipient where owner_email_id='%s'", pEmailId); 

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_TUPLES_OK){
		int numRows = PQntuples(pRes);
		char log_msg[512];
		sprintf(log_msg, "No. of recipeints: %d", numRows);
		LOG(debug, __FILE__, __LINE__, log_msg);
		for(int i = 0; i < numRows; i++) {
			RECIPIENT_DETAILS* pDetails = new RECIPIENT_DETAILS;
			pDetails->id = atol(PQgetvalue(pRes, i, 0));
			char *pTemp = PQgetvalue(pRes, i, 1);
			strcpy(pDetails->name, PQgetvalue(pRes, i, 1));
			pTemp = PQgetvalue(pRes, i, 2);
			strcpy(pDetails->emailId, PQgetvalue(pRes, i, 2));
			strcpy(pDetails->phone, PQgetvalue(pRes, i, 3));
			strcpy(pDetails->address, PQgetvalue(pRes, i, 4));
			strcpy(pDetails->relationship, PQgetvalue(pRes, i, 5));

			recipientList.push_back(pDetails);
		}
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the list of recipients corresponding to email id %s, Error: %s", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}
	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}

int ImaDbInterface::fetchRecipientList(unsigned long infoId, std::vector<unsigned long>& recipientList) {
	char log_msg[1024];
	sprintf(log_msg, "ImaDBInterface::fetchRecipientList called for info id: %lu", infoId);
	LOG(debug, __FILE__, __LINE__, log_msg);	
	
	int retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select recipient_id from tbl_info_recipient where info_id='%lu'", infoId); 

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_TUPLES_OK){
		int numRows = PQntuples(pRes);
		for(int i = 0; i < numRows; i++) {
			unsigned long recipient_id = atol(PQgetvalue(pRes, i, 0));
			recipientList.push_back(recipient_id);
		}
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the list of recipient ids corresponding to info id %lu, Error: %s", infoId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}

	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}


int ImaDbInterface::fetchInfoList(const char* pEmailId, std::vector<INFO_DETAILS*>& infoList) {
	char log_msg[1024];
	sprintf(log_msg, "ImaDbInterface::fetchInfoList called with emailid: %s", pEmailId);
	LOG(debug, __FILE__, __LINE__, log_msg);

	int retVal = 0;
	char query_string[1024];
	sprintf(query_string, "select info_id, info, media, doc, doe, ttl from tbl_info where owner_email_id='%s'", pEmailId); 

	PGresult* pRes = NULL;
	pRes = PQexec(mpConn, query_string);
	
	if(PQresultStatus(pRes) == PGRES_TUPLES_OK){
		int numRows = PQntuples(pRes);
		for(int i = 0; i < numRows; i++) {
			INFO_DETAILS* pDetails = new INFO_DETAILS;
			pDetails->id = atol(PQgetvalue(pRes, i, 0));
			strcpy(pDetails->info, PQgetvalue(pRes, i, 1));
			pDetails->media = atoi(PQgetvalue(pRes, i, 2));
			strcpy(pDetails->doc, PQgetvalue(pRes, i, 3));
			strcpy(pDetails->doe, PQgetvalue(pRes, i, 4));
			pDetails->ttl = atol(PQgetvalue(pRes, i, 5));
			if(1 != fetchRecipientList(pDetails->id, pDetails->recipients)) {
				sprintf(log_msg, "Failed to fetch list of recipients for info id: %lu",  pDetails->id);
				LOG(error , __FILE__, __LINE__, log_msg);
				retVal = 0;
			}
			infoList.push_back(pDetails);
		}
		retVal = 1;
	} else {
		char log_msg[512];
		sprintf(log_msg, "Failed to fetch the list of info corresponding to email id %s, Error: %s", pEmailId, PQresultErrorMessage(pRes));
		LOG(error, __FILE__, __LINE__, log_msg);
		retVal = 0;
	}

	//TODO: also handle database error
	PQclear(pRes);

	return retVal;
}
